package it.storm.solution;

/**
 * 794. 有效的井字游戏
 * https://leetcode-cn.com/problems/valid-tic-tac-toe-state/
 */
public class Solutions_794 {
    public static void main(String[] args) {
//        String[] board = {"O", " ", " "};  // output: false
//        String[] board = {"XOX", " X ", "   "};  // output: false
//        String[] board = {"XXX", "   ", "OOO"};  // output: false
        String[] board = {"XOX", "O O", "XOX"};  // output: true

        boolean result = validTicTacToe(board);
        System.out.println(result);
    }

    /**
     * 分类讨论，判断五子棋是否有效，不外乎 4 种情况，若棋盘上不满足该 4 种情况，就是有效的
     */
    public static boolean validTicTacToe(String[] board) {
        // 判断规则：分先后顺序
        // 1. 无论如何，字符 'O' 不可能比字符 'X' 多，因为字符 'X' 先放的
        // 2. 字符 'X' 最多比字符 'O' 多一个
        // 3. 字符 'X' 与字符 'O' 次数一样多时，说明最后落子的是 'O'，那么 'X' 之前的落子不可能胜
        // 4. 字符 'X' 比字符 'O' 多一次时，说明最后落子的是 'X'，那么 'O' 之前的落子不可能胜
        char[][] boards = new char[3][3];
        int xCount = 0, oCount = 0;
        for (int i = 0; i < 3; i++) {
            // 字符串转移到数组中
            boards[i] = board[i].toCharArray();
        }
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (boards[i][j] == 'X') {
                    xCount ++;
                } else if (boards[i][j] == 'O') {
                    oCount ++;
                }
            }
        }
        if (oCount > xCount) {
            return false;
        }
        if (xCount - 1 > oCount) {
            return false;
        }
        if (xCount == oCount) {
            // 如果 x 能够获取，return false
            return validSuccess(boards, 'X');
        }
        if (xCount - 1 == oCount) {
            // 如果 o 能够获取，return false
            return validSuccess(boards, 'O');
        }
        return true;
    }
    // 判断棋盘，优化版
    public static boolean validSuccess(char[][] boards, char owner) {
        for (int i = 0; i < 3; i++) {
            // 判断行是否相等
            if (boards[i][0] == boards[i][1] && boards[i][1] == boards[i][2] &&
                boards[i][2] == owner) {
                return false;
            }
            // 判断列是否相等
            if (boards[0][i] == boards[1][i] && boards[1][i] == boards[2][i] &&
                    boards[2][i] == owner) {
                return false;
            }
        }
        // 两条对角线
        if (boards[0][0] == boards[1][1] && boards[1][1] == boards[2][2] &&
                boards[2][2] == owner) {
            return false;
        }
        if (boards[0][2] == boards[1][1] && boards[1][1] == boards[2][0] &&
                boards[2][0] == owner) {
            return false;
        }
        return true;
    }

    public static boolean validSuccess2(char[][] boards, char owner) {
        // 三行
        if (boards[0][0] == boards[0][1] && boards[0][1] == boards[0][2] &&
                boards[0][2] == owner) {
            return false;
        }
        if (boards[1][0] == boards[1][1] && boards[1][1] == boards[1][2] &&
                boards[1][2] == owner) {
            return false;
        }
        if (boards[2][0] == boards[2][1] && boards[2][1] == boards[2][2] &&
                boards[2][2] == owner) {
            return false;
        }
        // 三列
        if (boards[0][0] == boards[1][0] && boards[1][0] == boards[2][0] &&
                boards[2][0] == owner) {
            return false;
        }
        if (boards[0][1] == boards[1][1] && boards[1][1] == boards[2][1] &&
                boards[2][1] == owner) {
            return false;
        }
        if (boards[0][2] == boards[1][2] && boards[1][2] == boards[2][2] &&
                boards[2][2] == owner) {
            return false;
        }
        // 两条对角线
        if (boards[0][0] == boards[1][1] && boards[1][1] == boards[2][2] &&
                boards[2][2] == owner) {
            return false;
        }
        if (boards[0][2] == boards[1][1] && boards[1][1] == boards[2][0] &&
                boards[2][0] == owner) {
            return false;
        }
        return true;
    }
}
